/*
 * TCSS 558
 * Distributed HashMap
 * Fall 2013
 * James Marquardt
 * Matt Adams
 * Justin Wong
 */
package node;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Set;

import model.Entry;
import model.HostPort;
import model.RemoteNodeData;
import model.RemoteNodeDataAndEntries;
/**
 * @author Matt Adams
 */
public interface RemoteNode extends Remote {
    
    /**
     * Returns the chord node that is responsible for the given target node id.
     * 
     * @param targetNodeID The target node id.
     * @return Returns node responsible for given node id.
     * @throws RemoteException RMI Remote Exception.
     */
    public RemoteNodeData findSuccessor(final int targetNodeID) throws RemoteException;
    
    /**
     * Stores the object under its given id.
     * 
     * @param entry Entry being inserted.
     * @throws RemoteException RMI Remote Exception.
     */
    public void insertEntry(final Entry entry) throws RemoteException;
    
    /**
     * Removes the object based on its given id.
     * 
     * @param entry Entry being removed.
     * @throws RemoteException RMI Remote Exception.
     */
    public void removeEntry(final Entry entry) throws RemoteException;
    
    /**
     * Returns whether the queried object is contained in a list under the given id.
     * 
     * @param entry Entry being checked for contains.
     * @return Returns true if object is found in the list under the given id.
     * @throws RemoteException RMI Remote Exception.
     */
    public boolean containsEntry(final Entry entry) throws RemoteException;
    
    /**
     * Returns the entry stored at the given key.
     * 
     * @param key the key the entry is stored at
     * @return the entry stored at the key
     * @throws RemoteException RMI Remote Exception.
     */
    public Entry getEntry(final int key) throws RemoteException;
    
    /**
     * Informs a node that its predecessor is leaving the chord.
     * 
     * @param predecessor Predecessor node leaving.
     * @throws RemoteException RMI Remote Exception.
     */
    public void leaveNetworkNotify(final RemoteNodeData predecessor) throws RemoteException;
    
    /**
     * Closes the connection to the node.
     * 
     * @throws RemoteException RMI Remote Exception.
     */
    public void closeConnections() throws RemoteException;
    
    /**
     * Opens the connection to the node.
     * 
     * @throws RemoteException RMI Remote Exception.
     */
    public void openConnections() throws RemoteException;
    
    
    /**
     * Notifies and updates a node with a potentially new predecessor reference. If the potential
     * predecessor is a more appropriate predecessor then the new predecessor will be set and 
     * entries will be transferred if needed. Entries are transferred if their IDs are in the interval 
     * (this node's old predecessor ID, new predecessor ID).The lower bound of the interval is excluded 
     * and the upper bound is included.
     * 
     * @param potentialPredecessor Potential predecessor.
     * @return Returns RemoteNodeData references and appropriate entries.
     * @throws RemoteException RMI Remote Exception.
     */
    public RemoteNodeDataAndEntries notifyWithPotentialPredecessor(RemoteNodeData potentialPredecessor) throws RemoteException;
    
    /**
     * @return Returns this node ID.
     * @throws RemoteException RMI Remote Exception.
     */
    public int getNodeID() throws RemoteException;
    
    /**
     * @return Returns this node's host and port.
     * @throws RemoteException RMI Remote Exception.
     */
    public HostPort getNodeHostPort() throws RemoteException;
    
    /**
     * @return Returns this node's predecessor.
     * @throws RemoteException RMI Remote Exception.
     */
    public RemoteNodeData getPredecessor() throws RemoteException;
    
    /**
     * @return Returns this node's successor.
     * @throws RemoteException RMI Remote Exception.
     */
    public RemoteNodeData getSuccessor() throws RemoteException;
    
    /**
     * @return Returns string representation of this node's references.
     * @throws RemoteException RMI Remote Exception.
     */
    public String remoteToString() throws RemoteException;
    
    /**
     * Sets this node's successor.
     * 
     * @param successorNode Node being set as successor.
     * @throws RemoteException RMI Remote Exception.
     */
    public void setSuccessor(RemoteNodeData successorNode) throws RemoteException;
    
    /**
     * Gets all entries for this node.
     * 
     * @return Returns RemoteNodeDataAndEntries containing all entries.
     * @throws RemoteException RMI Remote Exception.
     */
    public RemoteNodeDataAndEntries getEntries() throws RemoteException;
    
    /**
     * Adds all provided entries to this node's Entries.
     * 
     * @param entrySet Set of entries to add.
     * @throws RemoteException RMI Remote Exception.
     */
    public void addAllEntries(Set<Entry> entrySet) throws RemoteException;
    
    /**
     * Inserts a set of entry copies.
     * 
     * @param entryCopies Entry copies to insert.
     * @throws RemoteException RMI Remote Exception.
     */
    public void insertCopies(Set<Entry> entryCopies) throws RemoteException;
    
    /**
     * Removes a set of entry copies.
     * 
     * @param entryCopies Entry copies to remove.
     * @throws RemoteException RMI Remote Exception.
     */
    public void removeCopies(Set<Entry> entryCopies) throws RemoteException;
    
    /**
     * Checks whether node is still live.
     * 
     * @throws RemoteException RMI Remote Exception.
     */
    public void isLive() throws RemoteException;
}
